package spring.cloud.tasks.executor.name_space.executor.task.task_listener.task_statistics;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import spring.cloud.tasks.executor.common.Lifecycle;
import spring.cloud.tasks.executor.utils.LogUtils;

import java.util.Random;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;


@Slf4j
@Setter
@Getter
public class ExecutorTaskStatisticsReportTaskService implements Lifecycle {
    private String executorId;
    private ExecutorTaskStatisticsReportTask executorTaskStatisticsReportTask;
    private ScheduledExecutorService scheduledExecutorService;

    private ScheduledFuture<?> scheduledFuture;

    private boolean stop = false;

    public ExecutorTaskStatisticsReportTaskService(String executorId) {
        this.executorId = executorId;
        this.executorTaskStatisticsReportTask = new ExecutorTaskStatisticsReportTask(executorId);
    }


    @Override
    public synchronized void start() {

        scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
            private final AtomicInteger number = new AtomicInteger(0);

            @Override
            public Thread newThread(Runnable runnable) {
                StringBuilder name = new StringBuilder().append("-ProcessCount-Thread-").append(number.incrementAndGet());
                Thread thread = new Thread(runnable, name.toString());
                thread.setDaemon(false);
                thread.setPriority(Thread.NORM_PRIORITY);
                return thread;
            }
        });
        startProcessCountTask();
    }

    /**
     * 开启或重启统计处理数据数量的任务.
     */
    public synchronized void startProcessCountTask() {
        //
        /**
         * 统计任务处理数据数量的间隔时间.
         *
         * <p>
         * 单位: 秒. 只对处理数据流类型任务起作用.
         * </p>
         */
        int processCountIntervalSeconds = 300;
        if (processCountIntervalSeconds > 0) {
            if (scheduledFuture != null) {
                scheduledFuture.cancel(true);
                LogUtils.info(log, "Reschedule ProcessCountJob of the {} job, the processCountIntervalSeconds is {}", "");
            }
            scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(new ExecutorTaskStatisticsReportTask(executorId), new Random().nextInt(10), processCountIntervalSeconds, TimeUnit.SECONDS);

        } else { // don't count, reset to zero.
            if (scheduledFuture != null) {
                LogUtils.info(log, "shutdown the task of reporting statistics data", "");
                scheduledFuture.cancel(true);
                scheduledFuture = null;
            }
        }
    }


    @Override
    public void stop() {
        if (stop) {
            return;
        }
        stop = true;
        stopProcessCountJob();
        TaskStatistics.resetSuccessFailureCount(executorId);
    }

    /**
     * 停止统计处理数据数量的任务.
     */
    public synchronized void stopProcessCountJob() {
        if (scheduledFuture != null) {
            scheduledFuture.cancel(true);
        }
        if (scheduledExecutorService != null) {
            scheduledExecutorService.shutdown();
        }
    }
}
